"""
配置管理 API
提供系统配置、AI模型、Agent、设备等配置的管理接口
"""

import logging
from typing import List, Optional
from fastapi import APIRouter, HTTPException, status
from pydantic import BaseModel, Field

import database
from services.config_service import ConfigService

logger = logging.getLogger(__name__)

router = APIRouter()

def get_config_service() -> ConfigService:
    """获取配置服务实例（每次请求时动态创建）"""
    if database.db is None:
        raise HTTPException(
            status_code=500,
            detail="数据库未初始化，请确保服务已正确启动"
        )
    return ConfigService(database.db)


# ==================== 数据模型 ====================

class AIModelResponse(BaseModel):
    """AI模型响应模型"""
    id: int
    model_name: str
    provider: str
    api_key: str
    api_base: str
    model_type: str = "chat"
    temperature: float = 0.7
    max_tokens: int = 2048
    is_default: bool = False
    is_active: bool = True


class AIModelUpdate(BaseModel):
    """AI模型更新模型"""
    model_name: Optional[str] = None
    provider: Optional[str] = None
    api_key: Optional[str] = None
    api_base: Optional[str] = None
    model_type: Optional[str] = None
    temperature: Optional[float] = None
    max_tokens: Optional[int] = None
    is_default: Optional[bool] = None
    is_active: Optional[bool] = None


class AIModelCreate(BaseModel):
    """AI模型创建模型"""
    model_name: str
    provider: str
    api_key: str
    api_base: str
    model_type: str = "chat"
    temperature: float = 0.7
    max_tokens: int = 2048
    is_default: bool = False
    is_active: bool = True


class AgentResponse(BaseModel):
    """Agent响应模型"""
    id: int
    agent_code: str
    agent_name: str
    host: str = "localhost"
    port: int
    description: Optional[str] = None
    is_enabled: bool = True


class AgentUpdate(BaseModel):
    """Agent更新模型"""
    agent_name: Optional[str] = None
    host: Optional[str] = None
    port: Optional[int] = None
    description: Optional[str] = None
    is_enabled: Optional[bool] = None


class AgentPromptResponse(BaseModel):
    """Agent提示词响应模型"""
    agent_code: str
    prompt_text: str


class AgentPromptUpdate(BaseModel):
    """Agent提示词更新模型"""
    prompt_text: str
    version: str = "v1.0"


class DeviceResponse(BaseModel):
    """设备响应模型"""
    id: int
    device_code: str
    device_name: str
    device_type: str
    agent_code: str
    ip_address: Optional[str] = None
    token: Optional[str] = None
    model: Optional[str] = None
    extra_config: Optional[str] = None
    is_active: bool = True


class DeviceUpdate(BaseModel):
    """设备更新模型"""
    device_name: Optional[str] = None
    ip_address: Optional[str] = None
    token: Optional[str] = None
    model: Optional[str] = None
    extra_config: Optional[str] = None
    is_active: Optional[bool] = None


class DeviceCreate(BaseModel):
    """设备创建模型"""
    device_code: str
    device_name: str
    device_type: str
    agent_code: str
    ip_address: Optional[str] = None
    token: Optional[str] = None
    model: Optional[str] = None
    extra_config: Optional[str] = None
    is_active: bool = True


class XiaomiAccountResponse(BaseModel):
    """小米账号响应模型"""
    id: int
    username: str
    password: str
    region: str = "cn"
    is_default: bool = True
    is_active: bool = True


class XiaomiAccountUpdate(BaseModel):
    """小米账号更新模型"""
    username: Optional[str] = None
    password: Optional[str] = None
    region: Optional[str] = None
    is_default: Optional[bool] = None
    is_active: Optional[bool] = None


class XiaomiAccountCreate(BaseModel):
    """小米账号创建模型"""
    username: str
    password: str
    region: str = "cn"
    is_default: bool = True
    is_active: bool = True


class SystemConfigResponse(BaseModel):
    """系统配置响应模型"""
    id: int
    config_key: str
    config_value: str
    config_type: str
    category: str
    description: Optional[str] = None
    is_active: bool = True


class SystemConfigUpdate(BaseModel):
    """系统配置更新模型"""
    config_value: str


# ==================== AI 模型管理 ====================

@router.get("/ai-models", response_model=List[AIModelResponse])
async def get_ai_models(is_active: Optional[bool] = None):
    """获取AI模型配置列表"""
    try:
        config_service = get_config_service()
        models = config_service.get_ai_models(is_active)
        return models
    except Exception as e:
        logger.error(f"获取AI模型配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/ai-models/default", response_model=AIModelResponse)
async def get_default_ai_model():
    """获取默认AI模型配置"""
    try:
        config_service = get_config_service()
        model = config_service.get_default_ai_model()
        if not model:
            raise HTTPException(status_code=404, detail="未找到默认AI模型")
        return model
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取默认AI模型失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/ai-models/{model_id}", response_model=AIModelResponse)
async def get_ai_model(model_id: int):
    """根据ID获取AI模型配置"""
    try:
        config_service = get_config_service()
        model = config_service.get_ai_model_by_id(model_id)
        if not model:
            raise HTTPException(status_code=404, detail="未找到该AI模型")
        return model
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取AI模型失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/ai-models/{model_id}")
async def update_ai_model(model_id: int, data: AIModelUpdate):
    """更新AI模型配置"""
    try:
        config_service = get_config_service()
        update_data = data.model_dump(exclude_unset=True)
        success = config_service.update_ai_model(model_id, update_data)
        if not success:
            raise HTTPException(status_code=404, detail="更新失败或未找到该模型")
        return {"message": "更新成功", "model_id": model_id}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新AI模型失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/ai-models", status_code=status.HTTP_201_CREATED)
async def create_ai_model(data: AIModelCreate):
    """创建新的AI模型配置"""
    try:
        config_service = get_config_service()
        model_id = config_service.create_ai_model(data.model_dump())
        return {"message": "创建成功", "model_id": model_id}
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"创建AI模型失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== Agent 管理 ====================

@router.get("/agents", response_model=List[AgentResponse])
async def get_agents(is_enabled: Optional[bool] = None):
    """获取Agent配置列表"""
    try:
        config_service = get_config_service()
        agents = config_service.get_agents(is_enabled)
        return agents
    except Exception as e:
        logger.error(f"获取Agent配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/agents/{agent_code}", response_model=AgentResponse)
async def get_agent(agent_code: str):
    """根据代码获取Agent配置"""
    try:
        config_service = get_config_service()
        agent = config_service.get_agent_by_code(agent_code)
        if not agent:
            raise HTTPException(status_code=404, detail="未找到该Agent")
        return agent
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取Agent配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/agents/{agent_id}")
async def update_agent(agent_id: int, data: AgentUpdate):
    """更新Agent配置"""
    try:
        config_service = get_config_service()
        update_data = data.model_dump(exclude_unset=True)
        success = config_service.update_agent(agent_id, update_data)
        if not success:
            raise HTTPException(status_code=404, detail="更新失败或未找到该Agent")
        return {"message": "更新成功", "agent_id": agent_id}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新Agent配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/agents/{agent_code}/prompt", response_model=AgentPromptResponse)
async def get_agent_prompt(agent_code: str):
    """获取Agent的系统提示词"""
    try:
        config_service = get_config_service()
        prompt = config_service.get_agent_prompt(agent_code)
        if not prompt:
            raise HTTPException(status_code=404, detail="未找到该Agent的提示词")
        return {"agent_code": agent_code, "prompt_text": prompt}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取Agent提示词失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/agents/{agent_code}/prompt")
async def update_agent_prompt(agent_code: str, data: AgentPromptUpdate):
    """更新Agent的系统提示词"""
    try:
        config_service = get_config_service()
        success = config_service.update_agent_prompt(
            agent_code, data.prompt_text, data.version
        )
        if not success:
            raise HTTPException(status_code=404, detail="更新失败")
        return {"message": "提示词更新成功", "agent_code": agent_code}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新Agent提示词失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== 设备管理 ====================

@router.get("/devices", response_model=List[DeviceResponse])
async def get_devices(
    device_type: Optional[str] = None,
    is_active: Optional[bool] = None
):
    """获取设备配置列表"""
    try:
        config_service = get_config_service()
        devices = config_service.get_devices(device_type, is_active)
        return devices
    except Exception as e:
        logger.error(f"获取设备配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/devices/{device_code}", response_model=DeviceResponse)
async def get_device(device_code: str):
    """根据代码获取设备配置"""
    try:
        config_service = get_config_service()
        device = config_service.get_device_by_code(device_code)
        if not device:
            raise HTTPException(status_code=404, detail="未找到该设备")
        return device
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取设备配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/devices/{device_id}")
async def update_device(device_id: int, data: DeviceUpdate):
    """更新设备配置"""
    try:
        config_service = get_config_service()
        update_data = data.model_dump(exclude_unset=True)
        success = config_service.update_device(device_id, update_data)
        if not success:
            raise HTTPException(status_code=404, detail="更新失败或未找到该设备")
        return {"message": "更新成功", "device_id": device_id}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新设备配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/devices", status_code=status.HTTP_201_CREATED)
async def create_device(data: DeviceCreate):
    """创建新设备配置"""
    try:
        config_service = get_config_service()
        device_id = config_service.create_device(data.model_dump())
        return {"message": "创建成功", "device_id": device_id}
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"创建设备配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== 小米账号管理 ====================

@router.get("/xiaomi-accounts", response_model=List[XiaomiAccountResponse])
async def get_xiaomi_accounts(is_active: Optional[bool] = None):
    """获取小米账号配置列表"""
    try:
        config_service = get_config_service()
        accounts = config_service.get_xiaomi_accounts(is_active)
        return accounts
    except Exception as e:
        logger.error(f"获取小米账号配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/xiaomi-accounts/default", response_model=XiaomiAccountResponse)
async def get_default_xiaomi_account():
    """获取默认小米账号"""
    try:
        config_service = get_config_service()
        account = config_service.get_default_xiaomi_account()
        if not account:
            raise HTTPException(status_code=404, detail="未找到默认小米账号")
        return account
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取默认小米账号失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/xiaomi-accounts/{account_id}")
async def update_xiaomi_account(account_id: int, data: XiaomiAccountUpdate):
    """更新小米账号配置"""
    try:
        config_service = get_config_service()
        update_data = data.model_dump(exclude_unset=True)
        success = config_service.update_xiaomi_account(account_id, update_data)
        if not success:
            raise HTTPException(status_code=404, detail="更新失败或未找到该账号")
        return {"message": "更新成功", "account_id": account_id}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新小米账号失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/xiaomi-accounts", status_code=status.HTTP_201_CREATED)
async def create_xiaomi_account(data: XiaomiAccountCreate):
    """创建新小米账号"""
    try:
        config_service = get_config_service()
        account_id = config_service.create_xiaomi_account(data.model_dump())
        return {"message": "创建成功", "account_id": account_id}
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"创建小米账号失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ==================== 系统配置管理 ====================

@router.get("/system-config", response_model=List[SystemConfigResponse])
async def get_system_configs(category: Optional[str] = None):
    """获取系统配置列表"""
    try:
        config_service = get_config_service()
        configs = config_service.get_system_configs(category)
        return configs
    except Exception as e:
        logger.error(f"获取系统配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/system-config/{config_key}")
async def get_system_config(config_key: str):
    """根据键获取系统配置值"""
    try:
        config_service = get_config_service()
        value = config_service.get_system_config(config_key)
        if value is None:
            raise HTTPException(status_code=404, detail="未找到该配置项")
        return {"config_key": config_key, "config_value": value}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取系统配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/system-config/{config_key}")
async def update_system_config(config_key: str, data: SystemConfigUpdate):
    """更新系统配置"""
    try:
        config_service = get_config_service()
        success = config_service.update_system_config(config_key, data.config_value)
        if not success:
            raise HTTPException(status_code=404, detail="更新失败或未找到该配置项")
        return {"message": "更新成功", "config_key": config_key}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新系统配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))

